package TDAList;

import java.util.Iterator;


/**
 * Interface Lista para representar una secuencia
 * de n elementos: x1,x2,...,xn
 * 
 * @author Gonzalo Arró
 *
 * @param <E> parámetro genérico para representar 
 * el tipo de los elementos de la lista.
 */

public interface PositionList<E> extends Iterable<E> {
	
	/**
	 * Retorna la cantidad de elementos de la lista.
	 * 
	 * @return cantidad de elementos de la lista.
	 */
	
	public int size ();
	
	/**
	 * Consulta si la lista está vacía
	 * 
	 * @return true si la lista está vacía, false de otro modo.
	 */
	public boolean isEmpty ();
	
	/**
	 * Retorna la posición del primer elemento de la lista.
	 * 
	 * @return posición del primer elemento de la lista.
	 * 
	 * @throws EmptyListException si la lista está vacía.
	 */
	public Position<E> first () throws EmptyListException;
	
	/**
	 * Retorna la posición del último elemento de la lista.
	 * 
	 * @return posición del último elemento de la lista.
	 * 
	 * @throws EmptyListException si la lista está vacía.
	 */
	public Position<E> last () throws EmptyListException;
	
	/**
	 * Retorna la posición del elemento siguiente al de la posición pasada por parámetro.
	 * 
	 * @param p la posición en referencia a la cual se obtiene la siguiente.
	 * 
	 * @return la posición siguiente a p
	 * 
	 * @throws InvalidPositionException si la posición pasada por parámetro no es válida o la lista está vacía
	 * 
	 * @throws BoundaryViolationException si la posición pasada por parámetro es la última en la lista.
	 */
	public Position<E> next (Position<E> p) throws InvalidPositionException, BoundaryViolationException;
	
	/**
	 * Retorna la posición del elemento anterior al de la posición pasada por parámetro.
	 * 
	 * @param p la posición en referencia a la cual se obtiene la anterior.
	 * 
	 * @return la posición anterior a p
	 * 
	 * @throws InvalidPositionException si la posición pasada por parámetro no es válida o la lista está vacía
	 * 
	 * @throws BoundaryViolationException si la posición pasada por parámetro es la primera en la lista.
	 */
	public Position<E> prev (Position<E> p) throws InvalidPositionException, BoundaryViolationException;
	
	/**
	 * Añade un elemento al principio de la lista.
	 * 
	 * @param e el elemento a añadir a la lista.
	 */
	public void addFirst (E e);
	
	/**
	 * Añade un elemento al final de la lista.
	 * 
	 * @param e el elemento a añadir a la lista.
	 */
	public void addLast (E e);
	
	/**
	 * Inserta un nuevo elemento en la posición siguiente a la pasada por parámetro.
	 * 
	 * @param p posición en cuya posición siguiente se insertará el elemento.
	 * 
	 * @param e el elemento a insertar.
	 * 
	 * @throws InvalidPositionException  si la posición es inválida o la lista está vacía.
	 */
	public void addAfter (Position<E> p, E e) throws InvalidPositionException;
	
	/**
	 * Inserta un nuevo elemento en la posición anterior a la pasada por parámetro.
	 * 
	 * @param p posición en cuya posición anterior se insertará el elemento.
	 * 
	 * @param e el elemento a insertar.
	 * 
	 * @throws InvalidPositionException  si la posición es inválida o la lista está vacía.
	 */
	public void addBefore (Position<E> p, E e) throws InvalidPositionException;
	
	/**
	 * Remueve el elemento de la posición pasada por parámetro.
	 * 
	 * @param p posición del elemento a eliminar.
	 * 
	 * @return el elemento que se encontraba en la posición pasada por parámetro.
	 * 
	 * @throws InvalidPositionException si la posición pasada por parámetro es inválida o la lista está vacía.
	 */
	public E remove (Position<E> p) throws InvalidPositionException;
	
	/**
	 * Inserta un elemento pasado por parámetro en una posición pasada por parámetro.
	 * 
	 * @param p la posición donde se insertará el nuevo elemento.
	 * 
	 * @param e el elemento que se insertará en la posición pasada por parámetro.
	 * 
	 * @return el elemento que se encontraba en la posición pasada por parámetro.
	 * 
	 * @throws InvalidPositionException si la posición pasada por parámetro es inválida o la lista está vacía.
	 */
	public E set (Position<E> p, E e) throws InvalidPositionException;

	/**
	 * Devuelve un un iterador de todos los elementos de la lista.
	 * @return Un iterador de todos los elementos de la lista.
	 */
	public Iterator<E> iterator();
	
	/**
	 * Devuelve una colección iterable de posiciones.
	 * @return Una colección iterable de posiciones.
	 */
	public Iterable<Position<E>> positions();
}
